package com.soul.common.handler;


import cn.hutool.core.util.ObjectUtil;
import com.soul.common.exception.BaseException;
import com.soul.common.msg.ApiResult;
import com.soul.common.utils.FormatUtil;
import lombok.extern.log4j.Log4j2;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;

@Log4j2
@ControllerAdvice("com.soul")
@ResponseBody
public class GlobalExceptionHandler {



    @ExceptionHandler(BaseException.class)
    public ApiResult<Void> baseExceptionHandler(HttpServletResponse response, BaseException ex) {
        response.setStatus(200);
        if (ObjectUtils.isEmpty(ObjectUtil.toString(ex.getMessage()).trim())
                || "null".equalsIgnoreCase(FormatUtil.toString(ex.getMessage()).trim())) {

            log.error(ex.getMessage(), ex); //空指针输出异常路径
        } else {
            log.error(ex.getMessage()/*, ex*/);
        }
        return ApiResult.error(ex.getStatus(), ex.getMessage(), this.getDetailedMessage(ex));
    }

    @ExceptionHandler(Exception.class)
    public ApiResult<Void> otherExceptionHandler(HttpServletResponse response, Exception ex) {
        response.setStatus(200);
        log.error(ex.getMessage(), ex);
        return ApiResult.error(500, ex.getMessage(), this.getDetailedMessage(ex));
    }

    /**
     * 处理所有接口数据验证异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ApiResult<Void> handleMethodArgumentNotValidException(HttpServletResponse response, MethodArgumentNotValidException e) {

        List<ObjectError> errors = e.getBindingResult().getAllErrors();
        StringBuilder err = new StringBuilder();
        for (ObjectError error : errors) {
            if (err.length() > 0) {
                err.append("\n");
            }
            err.append(error.getDefaultMessage());
        }
        log.error(e.getMessage(), e);
        response.setStatus(200);
        return ApiResult.error(40401, err.toString());
    }

    /**
     * 得到异常详细信息
     *
     * @param e 异常
     * @return 异常详情
     */
    private String getDetailedMessage(Exception e) {
        StringWriter sw = new StringWriter();
        e.printStackTrace(new PrintWriter(sw, true));
        return sw.toString();
    }
}
